from tybase.tools.down_tools import FileDownloader
from tybase.tools.video_utils import create_video_from_images, get_audio_duration
import os
import requests
import ffmpeg

# 上传到阿里云

import sys

from config import kSlideOutputPath

sys.path.append("../..")
from utils import cloud_utils


class MyFileDownloader(FileDownloader):

    def download_file(self, url):
        # 计算URL的MD5值
        url_md5 = self.calculate_md5_for_string(url)
        # 获取文件的扩展名
        file_extension = os.path.splitext(url.split('?')[0])[-1]
        # 根据MD5值和扩展名确定文件名
        final_file_name = f"{url_md5}{file_extension}"
        final_file_path = os.path.join(self.save_dir, final_file_name)

        # 如果文件不存在，则下载
        if not os.path.exists(final_file_path):
            response = requests.get(url, stream=True)
            response.raise_for_status()
            with open(final_file_path, 'wb') as file:
                for chunk in response.iter_content(chunk_size=8192):
                    file.write(chunk)

        # 获取文件的时长
        duration = self.get_media_duration(final_file_path)

        return {'path': final_file_path, 'duration': duration}

    def get_media_duration(self, file_path):
        """获取文件的时长。如果无法获取，则返回None"""
        try:
            probe = ffmpeg.probe(file_path)
            return float(probe['format']['duration'])
        except Exception as e:
            print(f"无法获取文件的时长: {e}")
            return None


class MediaProcessor:
    def __init__(self):
        self.audio_downloader = MyFileDownloader(save_dir="./downloads/audio")
        self.images_downloader = MyFileDownloader(save_dir="./downloads/images")

    def down_load_images_files(self, urls):
        local_paths = [url for url in urls if os.path.exists(url)]
        if local_paths:
            return {"directory": os.path.dirname(local_paths[0]), "filepaths": local_paths}
        images_data = self.images_downloader.download_files(urls)
        return images_data

    def process_media(self, images_paths_urls, audio_file, transition_effect, output_file, transition_duration,
                      total_duration):
        images_paths = self.down_load_images_files(images_paths_urls)
        images_folder_path = images_paths["directory"]
        return create_video_from_images(images_folder_path, output_file, total_duration, transition_duration,
                                        transition_effect,
                                        audio_file=audio_file
                                        )


def start(audio_path, images_paths_urls, transition_effect, transition_duration):
    # 开始进行幻灯片的合成

    downloader = MyFileDownloader()
    audio_file_info = downloader.download_file(audio_path)
    # 计算保存的路径
    outptut_file_md5 = downloader.calculate_md5_for_string(audio_path + ','.join(images_paths_urls))
    output_file = "/{}.mp4".format(kSlideOutputPath, outptut_file_md5)

    processor = MediaProcessor()

    processor.process_media(images_paths_urls=images_paths_urls,
                            audio_file=audio_file_info["path"],
                            transition_effect=transition_effect,
                            output_file=output_file,
                            transition_duration=transition_duration,
                            total_duration=audio_file_info["duration"]
                            )

    ali_cloud_path = cloud_utils.transform_path(output_file, "Slides")
    aliyun_res = cloud_utils.upload_file_to_aliyun(ali_cloud_path, output_file)
    # 删除本地生成的视频文件
    os.remove(output_file)
    return aliyun_res


if __name__ == "__main__":
    # Models需要下面的信息
    transition_effect = "wiperight"
    transition_duration = 0.7
    audio_path = "https://ty-huanlian.oss-cn-shanghai.aliyuncs.com/output_audio.mp3"
    images_paths_urls = [
        "https://ty-huanlian.oss-cn-shanghai.aliyuncs.com/test/image1.jpg",
        "https://ty-huanlian.oss-cn-shanghai.aliyuncs.com/test/image2.jpg",
        "https://ty-huanlian.oss-cn-shanghai.aliyuncs.com/test/image3.jpg"
    ]

    start(audio_path, images_paths_urls, transition_effect, transition_duration)
